package services

import (
	comm "com.wangzhumo.lottery/common"
	"com.wangzhumo.lottery/dao"
	"com.wangzhumo.lottery/datasource"
	"com.wangzhumo.lottery/models"
	"encoding/json"
	"fmt"
	"log"
	"strconv"
	"strings"
)

// GiftServices 使用接口定义了Gift可以对外提供的功能
// 1.封装利于替换
// 2.可以有多种实现
type GiftServices interface {
	Get(id int,useCache bool) (*models.LtGift, error)
	GetAll(userCache bool) (list []models.LtGift, err error)
	GetAllInUse(useCache bool) []models.ObjectPrizeGift
	CountAll() int64
	Delete(id int) error
	DecrLeftNum(id int,num int) (int64,error)
	IncrLeftNum(id int,num int) (int64,error)
	Update(data *models.LtGift, columns []string) error
	Insert(data *models.LtGift) error
}

// 具体的实现
type giftServices struct {
	dao *dao.GiftDao
}

func (g *giftServices) Get(id int,useCache bool) (*models.LtGift, error) {
	if useCache {
		ltGifts, _ := g.GetAll(true)
		for _, gift := range ltGifts {
			if gift.Id == id {
				return &gift,nil
			}
		}
	}
	return g.dao.Get(id)
}

func (g *giftServices) GetAll(userCache bool) (list []models.LtGift, err error) {
	if userCache {
		allByCache := g.getAllByCache()
		if len(allByCache) < 1 {
			allByCache, _ = g.dao.GetAll()
			g.saveAllByCache(allByCache)
		}
		return allByCache,nil
	}
	return g.dao.GetAll()
}




func (g *giftServices) GetAllInUse(useCache bool) []models.ObjectPrizeGift {
	ltGifts := make([]models.LtGift,0)
	if !useCache {
		gifts, _ := g.GetAll(true)
		now := comm.NowUnix()
		// 过滤数据
		for _,gift := range gifts{
			if gift.Id >0 && gift.SysStatus == 0 && gift.PrizeNum > 0 && gift.TimeBegin <= now && gift.TimeEnd > now {
				ltGifts = append(ltGifts, gift)
			}
		}
	}else{
		ltGifts, _ := g.dao.GetAllInUse()
		fmt.Println(ltGifts)
	}


	if ltGifts != nil {
		gifts := make([]models.ObjectPrizeGift,0)
		for _, gift := range ltGifts {
			codes := strings.Split(gift.PrizeCode,"-")
			if len(codes) == 2 {
				// 为prizeCodeA  prizeCodeB 设置数据
				codeA := codes[0]
				codeB := codes[1]
				cA, err1 := strconv.Atoi(codeA)
				cB, err2 := strconv.Atoi(codeB)
				// 保证code合法
				if err1 == nil && err2 == nil && cB >= cA && cA > 0 && cB < 10000 {
					data := models.ObjectPrizeGift{
						Id:           gift.Id,
						Title:        gift.Title,
						PrizeNum:     gift.PrizeNum,
						LeftNum:      gift.LeftNum,
						PrizeCodeA:   cA,
						PrizeCodeB:   cB,
						Img:          gift.Img,
						Displayorder: gift.Displayorder,
						Gtype:        gift.Gtype,
						Gdata:        gift.Gdata,
					}
					gifts = append(gifts, data)
				}
			}
		}
		return gifts
	}

	return []models.ObjectPrizeGift{}
}


func (g *giftServices) CountAll() int64 {
	ltGifts, _ := g.GetAll(true)
	return int64(len(ltGifts))
}

func (g *giftServices) Delete(id int) error {
	// 先更新缓存的数据
	g.updateByCache(&models.LtGift{Id: id})
	return g.dao.Delete(id)
}

func (g *giftServices) DecrLeftNum(id int,num int) (int64,error) {
	return g.dao.DecrLeftNum(id,num)
}

func (g *giftServices) IncrLeftNum(id int,num int) (int64,error) {
	return g.dao.IncrLeftNum(id,num)
}


func (g *giftServices) Update(data *models.LtGift, columns []string) error {
	// 先更新缓存的数据
	g.updateByCache(data)
	return g.dao.Update(data, columns)
}

func (g *giftServices) Insert(data *models.LtGift) error {
	// 先更新缓存的数据
	g.updateByCache(data)
	return g.dao.Insert(data)
}

// 从redis中获取gift的全量数据
func (g *giftServices) getAllByCache() []models.LtGift {
	// 定义cache key
	key := "all_gift_redis"
	redisConn :=datasource.InstanceRedis()
	resp, err := redisConn.Do("GET", key)
	if err != nil {
		log.Println("giftService.getAllByCache GET key = ",key," err = ",err)
		return nil
	}
	if resp == "" {
		return nil
	}
	// 获取结构化的数据
	respStr := comm.GetString(resp, "")
	var dataList []map[string]interface{}
	err = json.Unmarshal([]byte(respStr), &dataList)
	if err != nil {
		log.Println("giftService.getAllByCache Unmarshal err = ",err)
		return nil
	}
	// 转换为[]LtGift
	giftList := make([]models.LtGift,len(dataList))
	for i, m := range dataList {
		giftId := comm.GetInt64FromMap(m, "Id", 0)
		if giftId < 0 {
			giftList[i] = models.LtGift{}
		}else{
			// PrizeData:  可能会很大，这里不去存储到redis
			giftList[i] = models.LtGift{
				Id: int(giftId),
				Title:        comm.GetStringFromMap(m,"Title",""),
				LeftNum:      int(comm.GetInt64FromMap(m,"LeftNum",0)),
				PrizeNum:     int(comm.GetInt64FromMap(m,"PrizeNum",0)),
				PrizeCode:    comm.GetStringFromMap(m,"PrizeCode",""),
				PrizeTime:    int(comm.GetInt64FromMap(m,"PrizeTime",0)),
				Img:          comm.GetStringFromMap(m,"Img",""),
				Displayorder: int(comm.GetInt64FromMap(m,"Displayorder",0)),
				Gtype:        int(comm.GetInt64FromMap(m,"Gtype",0)),
				Gdata:        comm.GetStringFromMap(m,"Gdata",""),
				TimeBegin:    int(comm.GetInt64FromMap(m,"TimeBegin",0)),
				TimeEnd:      int(comm.GetInt64FromMap(m,"TimeEnd",0)),
				PrizeBegin:   int(comm.GetInt64FromMap(m,"PrizeBegin",0)),
				PrizeEnd:     int(comm.GetInt64FromMap(m,"PrizeEnd",0)),
				SysStatus:    int(comm.GetInt64FromMap(m,"SysStatus",0)),
				SysCreated:   int(comm.GetInt64FromMap(m,"SysCreated",0)),
				SysUpdated:   int(comm.GetInt64FromMap(m,"SysUpdated",0)),
				SysIp:        comm.GetStringFromMap(m,"SysIp",""),
			}
		}
	}
	return giftList
}

// 保存所有的数据
func(g *giftServices) saveAllByCache(giftList []models.LtGift){
	giftListStr := ""
	if len(giftList) > 0 {
		// 循环添加数据
		giftListMap := make([]map[string]interface{},len(giftList))
		for i, gift := range giftList {
			data := make(map[string]interface{})
			data["Id"] = gift.Id
			data["Title"] = gift.Title
			data["LeftNum"] = gift.LeftNum
			data["PrizeNum"] = gift.PrizeNum
			data["PrizeCode"] = gift.PrizeCode
			data["PrizeTime"] = gift.PrizeTime
			data["Img"] = gift.Img
			data["Displayorder"] = gift.Displayorder
			data["Gtype"] = gift.Gtype
			data["Gdata"] = gift.Gdata
			data["TimeBegin"] = gift.TimeBegin
			data["TimeEnd"] = gift.TimeEnd
			data["PrizeBegin"] = gift.PrizeBegin
			data["PrizeEnd"] = gift.PrizeEnd
			data["SysStatus"] = gift.SysStatus
			data["SysCreated"] = gift.SysCreated
			data["SysUpdated"] = gift.SysUpdated
			data["SysIp"] = gift.SysIp

			// 写入
			giftListMap[i] = data
		}

		// save 到 redis
		giftListByte, err := json.Marshal(giftListMap)
		if err != nil {
			log.Println("giftService.saveAllByCache Marshal err",err)
		}
		giftListStr = string(giftListByte)
	}

	// 写入redis
	key := "all_gift_redis"
	redisConn := datasource.InstanceRedis()
	_, err := redisConn.Do("SET", key, giftListStr)
	if err != nil {
		log.Println("giftService.saveAllByCache redisConn SET = ",key," err = ", err)
	}
}

// 更新礼物，这里直接删除key重新读取即可
func (g *giftServices) updateByCache(gift *models.LtGift)  {
	if gift == nil || gift.Id <= 0 {
		return
	}
	// 否则删除
	key := "all_gift_redis"
	redisConn := datasource.InstanceRedis()
	_, err := redisConn.Do("DEL", key)
	if err != nil {
		log.Println("giftService.updateByCache redisConn DEL = ",key," err = ", err)
	}
}


func NewGiftServices() GiftServices {
	return &giftServices{
		dao: dao.NewGiftDao(datasource.InstanceDB()),
	}
}
